#include <stdio.h>
#include <sys/types.h>
#include <strings.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/param.h>

typedef void* (*func)();

extern int gDebug;
extern char *getenv();
extern char *strsave();
extern char *getdynpath();
extern char *which();

typedef enum { CC, CFRONT_1_2, CFRONT_2_0, GNU_CC } CCVersion;

CCVersion ccversion= GNU_CC;

static void *dummy()
{
	fprintf(stderr, "dynlink dummy called\n");
	return 0;
}

static char *mangle(name)
char *name;
{
	static char buf[MAXPATHLEN];

	switch (ccversion) {
	case CC:
		sprintf(buf, "_%s", name);
		break;
	case CFRONT_1_2:
		sprintf(buf, "_%s", name);
		break;
	case CFRONT_2_0:
		sprintf(buf, "_%s", name);
		break;
	case GNU_CC:
		sprintf(buf, "_%s__Fv", name);
		break;
	}
	return buf;
}

#if defined(GNU_DL)
#   include "dynlink.gnu_dld"
#else

#if defined(SUN_DL)
#include <dlfcn.h>

static void *mhandle;

func dld_load_more(progname, module, entry)
char *progname, *module, *entry;
{
	func fr= dummy, fp;
	char *path, buf[256];
		
	sprintf(buf, "%s.o", module);
	if (path= which(getdynpath(), buf, R_OK)) {
		mhandle= dlopen(path, 1);
		if (mhandle == 0) {
			fprintf(stderr, "dlopen(%s): %s\n", path, dlerror());
			return 0;
		}

		fp= dlsym(mhandle, "_init");
		if (fp == 0) {
			fprintf(stderr, "dlsym(_init): %s\n", dlerror());
			return 0;
		}
		(*fp)();

		if (entry) {
			fp= dlsym(mhandle, mangle(entry));
			if (fp == 0) {
				fprintf(stderr, "dlsym(%s): %s\n", mangle(entry), dlerror());
				fr= dummy;
				return 0;
			}
		}
	}
	return fr;
}

#else

func dld_load_more(progname, module, entry)
char *progname, *module, *entry;
{
	fprintf(stderr, "dld_load_more: %s %s %s\n", progname, module, entry);
	return dummy;
}

#endif
#endif


